
class Stack:
    def __init__(self):
        self.mylist = []  # 这里使用包含来实现

    def append(self,v):
        self.mylist.append(v)

    def push(self,v):
        self.mylist.append(v)

    def pop(self):
        return self.mylist.pop()

    def peek(self):
        return self.mylist[-1]

    def __len__(self):
        return len(self.mylist)

    def __contains__(self, item):
        return self.mylist.__contains__(item)

    def __getitem__(self, k):
        return self.mylist[k]

    def __iter__(self):
        self.current = 0
        return self

    def __next__(self):
        if self.current < len(self):
            self.current += 1
            return self.mylist[self.current - 1]
        else:
            raise StopIteration



st = Stack()
st.push(10)
st.push(20)
st.push(30)
st.push(40)
print('Size of stack is:',len(st))
print('First elem is:',st[0])
print('The top of the stack is:',st.peek())
print(st.pop())
print(st.pop())
print(st.pop())
print('Size of stack is:',len(st))

# 上面类的简化写法，值得深思
class Stacks(list):
    def push(self,v):
        self.append(v)

    def peek(self):
        return self[-1]



class Point:
    def __init__(self,x,y):
        self.x = x
        self.y = y

    def __mul__(self, other):
        if type(other) == Point:
            newx = self.x * other.x
            newy = self.y * other.y
            return Point(newx,newy)

        elif type(other) == int or type(other) == float:
            newx = self.x * other
            newy = self.y * other
            return Point(newx, newy)

        else:
            return NotImplemented

        # 也可以写成下面的形式
        # if isinstance(other,Point):
        #     newx = self.x * other.x
        #     newy = self.y * other.y
        #     return Point(newx, newy)
        #
        # elif isinstance(other,(int,float)):
        #     newx = self.x * other
        #     newy = self.y * other
        #     return Point(newx, newy)
        #
        # else:
        #     return NotImplemented

    def __rmul__(self, other):
        if isinstance(other,(int,float)):
            newx = self.x * other
            newy = self.y * other
            return Point(newx, newy)

        else:
            return NotImplemented


